import tkinter as tk
from tkinter import ttk, messagebox
import customtkinter as ctk
import platform
import os
import json
import random
import base64
import requests
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
import cursor_switcher

class MainApplication:
    def __init__(self, root):
        self.root = root
        self.root.title("cursor switcher")
        self.root.geometry("800x600")
        
        # 秘钥文件路径
        self.key_file_path = os.path.join(os.getcwd(), "cp_key.json")
        
        # 上次保存的秘钥值，用于减少文件写入
        self.last_saved_key = ""
        
        # 检测操作系统类型
        self.os_type = platform.system()
        
        # 设置深色主题
        ctk.set_appearance_mode("dark")
        ctk.set_default_color_theme("dark-blue")
        
        # 适配不同操作系统的字体
        self.configure_fonts()
        
        # 加载保存的秘钥
        self.saved_key = self.load_key()
        
        # 模拟数据
        self.mock_data = self.generate_mock_data()
        
        # 添加当前选中的标签页状态
        self.current_tab = "home"  # 默认显示首页
        
        # 后端API地址 - 移到这里
        self.api_base_url = "http://localhost:8080/api"
        
        # 检查API可用性 - 移到这里
        self.api_available = self.check_api_availability()
        
        # 添加顶部通知栏
        self.create_notification_bar()
        
        # 创建左侧导航栏
        self.create_sidebar()
        
        # 创建主内容区
        self.create_main_content()
        
        # 账号数据文件路径
        self.accounts_file_path = os.path.join(os.getcwd(), "cursor_accounts.json")
        
        # 初始化加密密钥
        self.setup_encryption()
        
        # 加载账号数据
        self.accounts = self.load_accounts()
        
        # 启动时获取当前Cursor登录的账号信息，延迟500毫秒执行，确保UI已完全加载
        self.root.after(500, self.get_current_cursor_email)
    
    def configure_fonts(self):
        """为不同操作系统配置合适的字体"""
        if self.os_type == "Darwin":  # macOS
            self.title_font = ("SF Pro", 16, "bold")
            self.normal_font = ("SF Pro", 12)
            self.small_font = ("SF Pro", 10)
        elif self.os_type == "Linux":
            self.title_font = ("Ubuntu", 16, "bold")
            self.normal_font = ("Ubuntu", 12)
            self.small_font = ("Ubuntu", 10)
        else:  # Windows 或其他
            self.title_font = ("Arial", 16, "bold")
            self.normal_font = ("Arial", 12)
            self.small_font = ("Arial", 10)
        
    def generate_mock_data(self):
        """生成模拟数据"""
        return {
            "key_status": "有效",
            "account_type": "Pro",
            "days_left": "26天",
            "local_cursor_email": "cursor@example.com",
            "cursor_status": "已注入客户端",
            "registration_date": "2025-03-27",
            "token": "xxxx-xxxx-xxxx-xxxx",
            "cursor_pool_usage": {
                "current": 0,
                "total": 1500
            },
            "advanced_model_usage": {
                "current": 0,
                "total": 150
            },
            "normal_model_usage": {
                "current": 0,
                "total": "无限制"
            }
        }
        
    def create_notification_bar(self):
        """创建顶部通知栏"""
        # 通知栏容器
        self.notification_frame = ctk.CTkFrame(self.root, height=30, fg_color="#1a1a1a")
        self.notification_frame.pack(fill="x", pady=(0, 5))
        
        # 从API获取通知
        self.notifications = self.fetch_notifications()
        
        # 如果无法获取通知，使用默认通知
        if not self.notifications:
            self.notifications = [
                ("欢迎使用cursor switcher", "#"),
            ]
        
        # 当前显示的消息索引
        self.current_notification = 0
        
        # 创建标签用于显示消息
        self.notification_label = ctk.CTkLabel(
            self.notification_frame,
            text="",
            font=self.normal_font,
            text_color="#ffffff",
            cursor="hand2"  # 鼠标悬停时显示手型光标
        )
        self.notification_label.pack(side="left", padx=15, pady=5)
        
        # 绑定点击事件
        self.notification_label.bind("<Button-1>", self.handle_notification_click)
        
        # 开始消息滚动
        self.update_notification()

    def update_notification(self):
        """更新显示的通知消息"""
        message, url = self.notifications[self.current_notification]
        
        # 更新标签文本
        self.notification_label.configure(text=message)
        
        # 根据是否有链接更新鼠标样式和文本颜色
        if url != "#":
            self.notification_label.configure(cursor="hand2", text_color="#4a9eff")
        else:
            self.notification_label.configure(cursor="arrow", text_color="#ffffff")
        
        # 更新索引
        self.current_notification = (self.current_notification + 1) % len(self.notifications)
        
        # 3秒后显示下一条消息
        self.root.after(3000, self.update_notification)

    def handle_notification_click(self, event):
        """处理通知消息点击事件"""
        # 获取当前消息的链接
        current_url = self.notifications[self.current_notification - 1][1]
        
        # 如果链接不是#，则打开链接
        if current_url != "#":
            import webbrowser
            webbrowser.open(current_url)

    def create_sidebar(self):
        sidebar = ctk.CTkFrame(self.root, width=60)
        sidebar.pack(side="left", fill="y")
        
        # 添加首页按钮
        self.home_btn = ctk.CTkButton(
            sidebar, 
            text="首页",
            font=self.normal_font,
            fg_color="#2d2d2d" if self.current_tab == "home" else "transparent",  # 选中状态
            hover_color="#3d3d3d",  # 更亮的悬停颜色
            width=60,
            height=40,
            command=self.handle_home_click
        )
        self.home_btn.pack(pady=(20, 5))
        
        # 修改账号管理按钮文本并调整位置 - 改为"Cursor账号"
        self.account_btn = ctk.CTkButton(
            sidebar, 
            text="Cursor账号",  # 修改文本
            font=self.normal_font,
            fg_color="#2d2d2d" if self.current_tab == "account" else "transparent",  # 选中状态
            hover_color="#3d3d3d",  # 更亮的悬停颜色
            width=60,
            height=40,
            command=self.handle_account_click
        )
        self.account_btn.pack(pady=5)
        
        # 将关于按钮放到账号管理按钮下方
        self.about_btn = ctk.CTkButton(
            sidebar, 
            text="关于",
            font=self.normal_font,
            fg_color="#2d2d2d" if self.current_tab == "about" else "transparent",  # 选中状态
            hover_color="#3d3d3d",  # 更亮的悬停颜色
            width=60,
            height=40,
            command=self.handle_about_click
        )
        self.about_btn.pack(pady=5)  # 保持相同的内边距

    def create_main_content(self):
        # 将main_container保存为类的属性，这样其他方法可以访问它
        self.main_container = ctk.CTkFrame(self.root, fg_color="transparent")
        self.main_container.pack(side="left", fill="both", expand=True, padx=10, pady=10)
        
        # 分成上半部分的两个框架
        top_frame = ctk.CTkFrame(self.main_container)
        top_frame.pack(fill="x", pady=(0, 10))
        
        # 在上半部分创建左右两个框架
        left_frame = ctk.CTkFrame(top_frame, width=380)
        left_frame.pack(side="left", fill="both", expand=True, padx=(0, 5))
        
        right_frame = ctk.CTkFrame(top_frame, width=380)
        right_frame.pack(side="right", fill="both", expand=True, padx=(5, 0))
        
        # 下方的快捷操作区域
        bottom_frame = ctk.CTkFrame(self.main_container)
        bottom_frame.pack(fill="x")
        
        # 填充用户信息
        self.create_user_info_section(left_frame)
        
        # 填充使用统计
        self.create_usage_stats_section(right_frame)
        
        # 填充快捷操作
        self.create_quick_actions_section(bottom_frame)
        
    def create_user_info_section(self, parent):
        # 标题
        title_label = ctk.CTkLabel(parent, text="用户信息", font=self.title_font)
        title_label.pack(anchor="w", padx=15, pady=(15, 10))
        
        # 秘钥状态信息 - 从API获取
        key_status_label = ctk.CTkLabel(parent, text=f"秘钥状态", font=self.normal_font)
        key_status_label.pack(anchor="w", padx=15, pady=(5, 0))
        
        # 创建动态值显示
        self.key_status_value = ctk.CTkLabel(
            parent, 
            text="加载中...", 
            font=self.normal_font
        )
        self.key_status_value.pack(anchor="w", padx=15, pady=(0, 10))
        
        # 启动异步加载许可证信息
        self.root.after(100, self.load_license_info)
        
        # 使用一条浅白色的分隔线，高度设置为1
        separator = ctk.CTkFrame(parent, height=2, fg_color="#dddddd")  # 纯白色，提高对比度
        separator.pack(fill="x", padx=15, pady=5)
        
        local_cursor_label = ctk.CTkLabel(parent, text="本地Cursor邮箱", font=self.normal_font)
        local_cursor_label.pack(anchor="w", padx=15, pady=(5, 0))
        
        cursor_email_frame = ctk.CTkFrame(parent, fg_color="transparent")
        cursor_email_frame.pack(anchor="w", fill="x", padx=15, pady=(0, 5))
        
        cursor_email_value = ctk.CTkLabel(
            cursor_email_frame, 
            text=f"{self.mock_data['local_cursor_email']}", 
            font=self.normal_font
        )
        cursor_email_value.pack(side="left")
        
        change_btn = ctk.CTkButton(
            cursor_email_frame, 
            text="已验证", 
            font=self.small_font,
            fg_color="#065f46", 
            hover_color="#064e3b",
            width=60,
            height=25
        )
        change_btn.pack(side="left", padx=10)
        
        # 本地Cursor状态 - 修改为内联显示
        cursor_status_frame = ctk.CTkFrame(parent, fg_color="transparent")
        cursor_status_frame.pack(anchor="w", fill="x", padx=15, pady=(5, 5))
        
        cursor_status_label = ctk.CTkLabel(
            cursor_status_frame, 
            text="本地Cursor状态", 
            font=self.normal_font
        )
        cursor_status_label.pack(side="left", pady=(0, 0))
        
        status_btn = ctk.CTkButton(
            cursor_status_frame, 
            text=f"{self.mock_data['cursor_status']}", 
            font=self.small_font,
            fg_color="#1e3a8a", 
            hover_color="#1e40af",
            width=100,
            height=25
        )
        status_btn.pack(side="left", padx=(10, 0))
        
        # 新增刷新按钮
        refresh_btn = ctk.CTkButton(
            cursor_status_frame,
            text="刷新",
            font=self.small_font,
            fg_color="#10b981",
            hover_color="#059669",
            width=60,
            height=25,
            command=self.get_current_cursor_email
        )
        refresh_btn.pack(side="left", padx=(5, 0))
        
        # 本地Cursor账户注册时间 - 修改为内联显示并移除token
        reg_date_frame = ctk.CTkFrame(parent, fg_color="transparent")
        reg_date_frame.pack(anchor="w", fill="x", padx=15, pady=(5, 5))  # 减少底部内边距
        
        reg_date_label = ctk.CTkLabel(
            reg_date_frame, 
            text="本地Cursor账户注册时间", 
            font=self.normal_font
        )
        reg_date_label.pack(side="left", pady=(0, 0))
        
        reg_date_value = ctk.CTkLabel(
            reg_date_frame, 
            text=f"{self.mock_data['registration_date']}", 
            font=self.normal_font
        )
        reg_date_value.pack(side="left", padx=(10, 0))
        
        # 修改 - 添加token显示，显示前32位
        token_frame = ctk.CTkFrame(parent, fg_color="transparent")
        token_frame.pack(anchor="w", fill="x", padx=15, pady=(0, 15))  # 设置底部内边距
        
        # 存储token值标签的引用，方便后续更新
        self.token_value_label = ctk.CTkLabel(
            token_frame,
            text=self.get_token_prefix(self.mock_data['token'], 32),  # 改为显示前32位
            font=self.small_font,
            text_color="#6b7280"  # 使用浅灰色
        )
        self.token_value_label.pack(side="left")

    def create_usage_stats_section(self, parent):
        # 标题
        title_label = ctk.CTkLabel(parent, text="使用统计", font=self.title_font)
        title_label.pack(anchor="w", padx=15, pady=(15, 20))
        
        # Cursor Pool额度使用量
        pool_label = ctk.CTkLabel(
            parent, 
            text=f"Cursor Pool额度使用量", 
            font=self.normal_font
        )
        pool_label.pack(anchor="w", padx=15, pady=(5, 0))
        
        pool_frame = ctk.CTkFrame(parent, fg_color="transparent")
        pool_frame.pack(fill="x", padx=15, pady=(0, 15))
        
        pool_progress = ctk.CTkProgressBar(pool_frame, height=8)
        pool_progress.pack(side="left", fill="x", expand=True, pady=10)
        pool_progress.set(self.mock_data['cursor_pool_usage']['current'] / self.mock_data['cursor_pool_usage']['total'])
        
        pool_value = ctk.CTkLabel(
            pool_frame, 
            text=f"{self.mock_data['cursor_pool_usage']['current']}/{self.mock_data['cursor_pool_usage']['total']}", 
            font=self.normal_font
        )
        pool_value.pack(side="right", padx=(10, 0))
        
        # 高级模型使用量
        advanced_label = ctk.CTkLabel(
            parent, 
            text=f"高级模型使用量", 
            font=self.normal_font
        )
        advanced_label.pack(anchor="w", padx=15, pady=(5, 0))
        
        advanced_frame = ctk.CTkFrame(parent, fg_color="transparent")
        advanced_frame.pack(fill="x", padx=15, pady=(0, 15))
        
        advanced_progress = ctk.CTkProgressBar(advanced_frame, height=8, progress_color="#10b981")
        advanced_progress.pack(side="left", fill="x", expand=True, pady=10)
        advanced_progress.set(self.mock_data['advanced_model_usage']['current'] / self.mock_data['advanced_model_usage']['total'])
        
        advanced_value = ctk.CTkLabel(
            advanced_frame, 
            text=f"{self.mock_data['advanced_model_usage']['current']}/{self.mock_data['advanced_model_usage']['total']}", 
            font=self.normal_font
        )
        advanced_value.pack(side="right", padx=(10, 0))
        
        # 普通模型使用量
        normal_label = ctk.CTkLabel(
            parent, 
            text=f"普通模型使用量", 
            font=self.normal_font
        )
        normal_label.pack(anchor="w", padx=15, pady=(5, 0))
        
        normal_frame = ctk.CTkFrame(parent, fg_color="transparent")
        normal_frame.pack(fill="x", padx=15, pady=(0, 15))
        
        normal_progress = ctk.CTkProgressBar(normal_frame, height=8, progress_color="#10b981")
        normal_progress.pack(side="left", fill="x", expand=True, pady=10)
        normal_progress.set(1.0)  # 设置为100%，因为无限制
        
        normal_value = ctk.CTkLabel(
            normal_frame, 
            text=f"{self.mock_data['normal_model_usage']['current']}/{self.mock_data['normal_model_usage']['total']}", 
            font=self.normal_font
        )
        normal_value.pack(side="right", padx=(10, 0))
        
    def create_quick_actions_section(self, parent):
        # 标题
        title_label = ctk.CTkLabel(parent, text="快捷操作", font=self.title_font)
        title_label.pack(anchor="w", padx=15, pady=(15, 20))
        
        # 创建框架来包含输入框和按钮
        action_frame = ctk.CTkFrame(parent, fg_color="transparent")
        action_frame.pack(fill="x", pady=10, padx=15)
        
        # 添加秘钥输入提示和输入框
        key_label = ctk.CTkLabel(
            action_frame, 
            text="秘钥:", 
            font=self.normal_font
        )
        key_label.pack(anchor="w", pady=(0, 5))
        
        # 秘钥输入框
        self.key_entry = ctk.CTkEntry(
            action_frame,
            width=400,
            font=self.normal_font,
            placeholder_text="请输入激活秘钥"
        )
        self.key_entry.pack(fill="x", pady=(0, 10))
        
        # 如果有保存的秘钥，自动填入
        if self.saved_key:
            self.key_entry.insert(0, self.saved_key)
        
        # 绑定输入事件，实时保存秘钥
        self.key_entry.bind("<KeyRelease>", self.save_key_on_type)
        
        # 添加一键更换按钮 - 居中显示
        button_frame = ctk.CTkFrame(action_frame, fg_color="transparent")
        button_frame.pack(fill="x")
        
        quick_action_btn = ctk.CTkButton(
            button_frame, 
            text="一键更换(账户+机器码)", 
            font=self.normal_font,
            fg_color="#10b981", 
            hover_color="#059669",
            width=200,
            height=35,
            command=self.handle_quick_action
        )
        quick_action_btn.pack(pady=10)
    
    def handle_quick_action(self):
        """处理一键更换按钮点击事件"""
        # 获取输入的秘钥
        key = self.key_entry.get()
        
        if not key:
            # 如果没有输入秘钥，显示错误提示
            messagebox.showerror("错误", "请输入秘钥")
            return
        
        # 首先尝试重置机器码，无论成功与否都继续执行
        try:
            # 创建CursorAccountSwitcher实例
            switcher = cursor_switcher.CursorAccountSwitcher()
            
            # 调用重置机器码方法
            machine_code_reset = switcher.modify_machine_code()
            if machine_code_reset:
                print("机器码重置成功")
            else:
                print("机器码重置可能部分成功或失败")
        except Exception as e:
            print(f"重置机器码时出错: {e}")
            # 继续执行，不中断流程
        
        # 调用API获取账号
        try:
            response = requests.get(f"{self.api_base_url}/account/{key}", timeout=10)
            
            if response.status_code == 200:
                # 成功获取账号
                account_data = response.json()
                print(f"获取账号成功: {account_data}")  # 调试信息
                
                email = account_data.get('email', '')
                token = account_data.get('token', '')
                
                # 获取积分信息
                points_used = int(account_data.get('points_used', 0))
                points_remaining = int(account_data.get('points_remaining', 0))
                
                # 执行账号更换操作
                success = False
                if self.os_type == "Darwin":  # macOS
                    success = self.perform_account_switch_mac(email, token)
                elif self.os_type == "Linux":
                    success = self.perform_account_switch_linux(email, token)
                else:  # Windows 或其他
                    success = self.perform_account_switch_windows(email, token)
                
                if not success:
                    messagebox.showwarning("警告", "账号信息已获取，但切换操作可能未成功。\n请手动检查配置是否已更新。")
                
                # 更新UI显示
                self.mock_data['local_cursor_email'] = email
                self.mock_data['token'] = token
                
                # 使用正确的积分逻辑更新UI数据
                total_points = points_used + points_remaining
                self.mock_data['cursor_pool_usage']['total'] = total_points
                self.mock_data['cursor_pool_usage']['current'] = points_used
                
                # 直接更新积分显示
                self.update_cursor_pool_display(points_used, total_points)
                
                # 将新账号添加到账号列表（后台操作，不切换页面）
                self.add_account(email, token)
                
                # 更新首页界面
                self.update_ui_with_account_info()
                
                # 显示成功消息
                messagebox.showinfo("成功", f"已成功更换账号\n邮箱: {email}\n剩余积分: {points_remaining}")
                
            elif response.status_code == 403:
                # 无权限或积分不足
                error_data = response.json()
                error_msg = error_data.get('error', '未知错误')
                messagebox.showerror("错误", f"无法获取账号: {error_msg}")
            else:
                # 其他错误
                messagebox.showerror("错误", f"获取账号失败，错误代码: {response.status_code}")
                
        except requests.exceptions.ConnectionError:
            messagebox.showinfo("连接提示", "服务暂时无法访问，请稍后再试。")
            print("服务器连接失败，无法执行一键更换操作")
        except Exception as e:
            messagebox.showerror("错误", f"网络连接错误: {str(e)}")
            print(f"获取账号时出错: {e}")

    def perform_account_switch_mac(self, email, token):
        """在macOS上执行账号切换"""
        # 调用cursor_switcher.py中的方法
        success = cursor_switcher.switch_account_mac(email, token)
        return success

    def perform_account_switch_linux(self, email, token):
        """在Linux上执行账号切换"""
        # 调用cursor_switcher.py中的方法
        success = cursor_switcher.switch_account_linux(email, token)
        return success

    def perform_account_switch_windows(self, email, token):
        """在Windows上执行账号切换"""
        # 调用cursor_switcher.py中的方法
        success = cursor_switcher.switch_account_windows(email, token)
        return success

    def update_ui_with_account_info(self):
        """更新界面上的账号信息"""
        # 遍历所有子控件，查找并更新包含邮箱的标签
        for widget in self.root.winfo_children():
            self.update_widgets_recursive(widget)
        
        # 更新进度条和使用量显示
        self.update_usage_stats()
        
        # 刷新界面
        self.root.update()

    def update_usage_stats(self):
        """更新使用统计信息"""
        # 遍历所有子控件，查找并更新进度条和使用量显示
        for widget in self.root.winfo_children():
            if isinstance(widget, ctk.CTkFrame):
                for child in widget.winfo_children():
                    if isinstance(child, ctk.CTkFrame):
                        # 查找进度条和标签
                        progress_bar = None
                        pool_value_label = None
                        
                        for item in child.winfo_children():
                            if isinstance(item, ctk.CTkProgressBar):
                                progress_bar = item
                            elif isinstance(item, ctk.CTkLabel) and hasattr(item, 'cget'):
                                text = item.cget('text')
                                if '/' in text and "cursor_pool_usage" in str(item):
                                    pool_value_label = item
                        
                        # 如果找到了进度条和标签，更新它们
                        if progress_bar and self.mock_data['cursor_pool_usage']['total'] > 0:
                            # 进度条应该显示已使用比例
                            used_ratio = self.mock_data['cursor_pool_usage']['current'] / self.mock_data['cursor_pool_usage']['total']
                            progress_bar.set(used_ratio)
                            
                        if pool_value_label:
                            # 更新标签文本为"已使用/总量"
                            pool_value_label.configure(
                                text=f"{self.mock_data['cursor_pool_usage']['current']}/{self.mock_data['cursor_pool_usage']['total']}"
                            )

    def update_widgets_recursive(self, widget):
        """递归更新所有子控件中的账号信息"""
        if isinstance(widget, ctk.CTkLabel):
            # 更新显示邮箱的标签
            if hasattr(widget, 'cget') and widget.cget('text') == self.mock_data['local_cursor_email']:
                widget.configure(text=self.mock_data['local_cursor_email'])
        
        # 递归处理所有子控件
        if hasattr(widget, 'winfo_children'):
            for child in widget.winfo_children():
                self.update_widgets_recursive(child)

    def load_key(self):
        """从文件加载保存的秘钥"""
        try:
            if os.path.exists(self.key_file_path):
                with open(self.key_file_path, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    return data.get('key', '')
            return ''
        except Exception as e:
            print(f"加载秘钥时出错: {e}")
            return ''

    def save_key(self, key):
        """将秘钥保存到文件"""
        # 如果与上次保存的值相同，跳过保存
        if key == self.last_saved_key:
            return True
        
        try:
            with open(self.key_file_path, 'w', encoding='utf-8') as f:
                json.dump({'key': key}, f, ensure_ascii=False)
            # 更新上次保存的值
            self.last_saved_key = key
            return True
        except Exception as e:
            print(f"保存秘钥时出错: {e}")
            return False

    def save_key_on_type(self, event):
        """当用户输入时实时保存秘钥"""
        key = self.key_entry.get()
        # 静默保存，不显示任何提示
        if self.save_key(key):
            # 如果秘钥发生变化，重新加载许可证信息
            if self.api_available:
                self.load_license_info()

    def handle_home_click(self):
        """处理首页按钮点击事件"""
        if self.current_tab != "home":
            self.current_tab = "home"
            # 更新按钮状态
            self.home_btn.configure(fg_color="#2d2d2d")
            self.about_btn.configure(fg_color="transparent")
            self.account_btn.configure(fg_color="transparent")  # 更新账号管理按钮状态
            # 显示主页内容
            self.show_home_content()

    def handle_about_click(self):
        """处理关于按钮点击事件"""
        if self.current_tab != "about":
            self.current_tab = "about"
            # 更新按钮状态
            self.home_btn.configure(fg_color="transparent")
            self.about_btn.configure(fg_color="#2d2d2d")
            self.account_btn.configure(fg_color="transparent")  # 更新账号管理按钮状态
            # 显示关于页面内容
            self.show_about_content()

    def show_home_content(self):
        """显示首页内容"""
        # 确保主内容区可见
        if hasattr(self, 'about_frame'):
            self.about_frame.pack_forget()
        
        # 正确隐藏账号管理页面 - 修复这一部分
        # 先检查是否存在属性，如果存在则进行隐藏
        if hasattr(self, 'account_frame') and self.account_frame.winfo_exists():
            self.account_frame.pack_forget()
        
        self.main_container.pack(side="left", fill="both", expand=True, padx=10, pady=10)

    def show_about_content(self):
        """显示关于页面内容"""
        # 隐藏主内容区
        self.main_container.pack_forget()
        
        # 正确隐藏账号管理页面 - 修复这一部分
        # 先检查是否存在属性，如果存在则进行隐藏
        if hasattr(self, 'account_frame') and self.account_frame.winfo_exists():
            self.account_frame.pack_forget()
        
        # 创建或显示关于页面
        if not hasattr(self, 'about_frame'):
            self.about_frame = ctk.CTkFrame(self.root, fg_color="transparent")
            about_title = ctk.CTkLabel(
                self.about_frame, 
                text="关于 Cursor Switcher", 
                font=self.title_font
            )
            about_title.pack(pady=(30, 20))
            
            about_text = ctk.CTkLabel(
                self.about_frame,
                text="Cursor Switcher\n\n版本: 1.0.0\n作者: Your Name\n\n© 2024 All Rights Reserved",
                font=self.normal_font
            )
            about_text.pack(pady=20)
        
        self.about_frame.pack(side="left", fill="both", expand=True, padx=10, pady=10)

    def handle_account_click(self):
        """处理账号管理按钮点击事件"""
        if self.current_tab != "account":
            self.current_tab = "account"
            # 更新按钮状态
            self.home_btn.configure(fg_color="transparent")
            self.about_btn.configure(fg_color="transparent")
            self.account_btn.configure(fg_color="#2d2d2d")
            # 显示账号管理页面内容
            self.show_account_content()

    def show_account_content(self):
        """显示账号管理页面内容"""
        # 隐藏其他内容
        self.main_container.pack_forget()
        if hasattr(self, 'about_frame'):
            self.about_frame.pack_forget()
        
        # 创建或显示账号管理页面
        if not hasattr(self, 'account_frame') or True:  # 始终重建以刷新列表
            if hasattr(self, 'account_frame'):
                self.account_frame.destroy()
            
            # 初始化分页数据
            if not hasattr(self, 'account_page'):
                self.account_page = 1
            if not hasattr(self, 'accounts_per_page'):
                self.accounts_per_page = 5
            
            self.account_frame = ctk.CTkFrame(self.root, fg_color="transparent")
            
            # 添加标题
            account_title = ctk.CTkLabel(
                self.account_frame, 
                text="账号管理", 
                font=self.title_font
            )
            account_title.pack(pady=(30, 20))
            
            # 创建账号管理内容框架
            account_content = ctk.CTkFrame(self.account_frame)
            account_content.pack(fill="both", expand=True, padx=20, pady=10)
            
            # 添加表头
            header_frame = ctk.CTkFrame(account_content, fg_color="#1a1a1a", height=40)
            header_frame.pack(fill="x", padx=15, pady=(15, 0))
            header_frame.pack_propagate(False)  # 防止高度被内容压缩
            
            # 邮箱列标题
            email_header = ctk.CTkLabel(
                header_frame,
                text="邮箱",
                font=self.normal_font,
                anchor="w"
            )
            email_header.pack(side="left", padx=(15, 0))
            
            # 机器码列标题 - 调整位置
            machine_header = ctk.CTkLabel(
                header_frame,
                text="机器码",
                font=self.normal_font,
                anchor="w"
            )
            machine_header.pack(side="left", padx=(150, 0))  # 调整间距
            
            # 高级模型使用量列标题 - 调整位置
            usage_header = ctk.CTkLabel(
                header_frame,
                text="高级模型使用量",
                font=self.normal_font,
                anchor="w"
            )
            usage_header.pack(side="left", padx=(80, 0))  # 调整间距
            
            # 操作列标题
            action_header = ctk.CTkLabel(
                header_frame,
                text="操作",
                font=self.normal_font,
                anchor="e"
            )
            action_header.pack(side="right", padx=(0, 30))
            
            # 添加分隔线
            separator = ctk.CTkFrame(account_content, height=1, fg_color="#333333")
            separator.pack(fill="x", padx=15, pady=(0, 5))
            
            # 从数据中加载账号 - 仅加载当前页的账号
            if self.accounts and len(self.accounts) > 0:
                # 计算总页数
                total_pages = (len(self.accounts) + self.accounts_per_page - 1) // self.accounts_per_page
                
                # 确保当前页不超过总页数
                if self.account_page > total_pages:
                    self.account_page = total_pages
                
                # 计算当前页的起始和结束索引
                start_idx = (self.account_page - 1) * self.accounts_per_page
                end_idx = min(start_idx + self.accounts_per_page, len(self.accounts))
                
                # 显示当前页的账号
                for i in range(start_idx, end_idx):
                    account = self.accounts[i]
                    self.create_account_item(
                        account_content, 
                        account["email"], 
                        account["status"]
                    )
            else:
                # 如果没有账号，显示提示信息
                no_accounts_label = ctk.CTkLabel(
                    account_content,
                    text="暂无cursor账号",
                    font=self.normal_font,
                    text_color="gray60"
                )
                no_accounts_label.pack(pady=20)
            
            # 添加新增账号按钮
            add_btn_frame = ctk.CTkFrame(account_content, fg_color="transparent")
            add_btn_frame.pack(fill="x", padx=15, pady=15)
            
            add_account_btn = ctk.CTkButton(
                add_btn_frame,
                text="+ 添加新账号",
                font=self.normal_font,
                fg_color="#1e40af",
                hover_color="#1e3a8a",
                height=35,
                command=self.handle_add_account
            )
            add_account_btn.pack(side="left")
            
            # 添加分页控件
            pagination_frame = ctk.CTkFrame(account_content, fg_color="transparent")
            pagination_frame.pack(fill="x", padx=15, pady=(5, 10))
            
            # 计算总页数
            total_pages = max(1, (len(self.accounts) + self.accounts_per_page - 1) // self.accounts_per_page)
            
            # 上一页按钮
            prev_btn = ctk.CTkButton(
                pagination_frame,
                text="<",
                font=self.small_font,
                fg_color="#333333",
                hover_color="#444444",
                width=30,
                height=30,
                command=self.handle_prev_page,
                state="disabled" if self.account_page <= 1 else "normal"
            )
            prev_btn.pack(side="left", padx=(250, 5))
            
            # 页码标签
            self.page_label = ctk.CTkLabel(
                pagination_frame,
                text=f"{self.account_page}/{total_pages}",
                font=self.small_font,
                width=60,
                height=30,
                fg_color="#10b981",
                corner_radius=5
            )
            self.page_label.pack(side="left")
            
            # 下一页按钮
            next_btn = ctk.CTkButton(
                pagination_frame,
                text=">",
                font=self.small_font,
                fg_color="#333333",
                hover_color="#444444",
                width=30,
                height=30,
                command=self.handle_next_page,
                state="disabled" if self.account_page >= total_pages else "normal"
            )
            next_btn.pack(side="left", padx=(5, 0))
        
        # 显示账号管理页面
        self.account_frame.pack(side="left", fill="both", expand=True, padx=10, pady=10)

    def create_account_item(self, parent, email, status):
        """创建账号列表项"""
        item_frame = ctk.CTkFrame(parent, fg_color="#1e1e1e", height=50)
        item_frame.pack(fill="x", padx=15, pady=3)
        item_frame.pack_propagate(False)  # 防止高度被内容压缩
        
        # 邮箱
        email_label = ctk.CTkLabel(
            item_frame,
            text=email,
            font=self.normal_font,
            anchor="w",
            width=150  # 固定宽度
        )
        email_label.pack(side="left", padx=15)
        
        # 机器码 - 调整位置
        token_display = self.mask_token(self.get_account_token(email))
        token_label = ctk.CTkLabel(
            item_frame,
            text=token_display,
            font=self.normal_font,
            anchor="w",
            width=120  # 固定宽度
        )
        token_label.pack(side="left", padx=(10, 0))  # 调整间距
        
        # 高级模型使用量 - 调整位置和布局
        usage_percent = random.randint(0, 100)
        usage_frame = ctk.CTkFrame(item_frame, fg_color="transparent", width=150)
        usage_frame.pack(side="left", padx=(10, 0))  # 调整间距
        
        # 进度条背景
        progress_bg = ctk.CTkFrame(usage_frame, fg_color="#333333", height=10, width=100)
        progress_bg.pack(side="left", pady=10)
        
        # 进度条前景 - 根据使用率显示不同颜色
        progress_color = "#ef4444" if usage_percent > 70 else "#10b981"
        progress_width = int(usage_percent)
        if progress_width > 0:
            progress_fg = ctk.CTkFrame(
                progress_bg, 
                fg_color=progress_color, 
                height=10, 
                width=progress_width
            )
            progress_fg.place(x=0, y=0)
        
        # 使用百分比
        percent_label = ctk.CTkLabel(
            usage_frame,
            text=f"{usage_percent}%",
            font=self.small_font,
            text_color="gray70"
        )
        percent_label.pack(side="left", padx=(5, 0))  # 调整间距
        
        # 操作按钮
        action_frame = ctk.CTkFrame(item_frame, fg_color="transparent")
        action_frame.pack(side="right", padx=15)
        
        # 切换按钮
        switch_btn = ctk.CTkButton(
            action_frame,
            text="切换",
            font=self.small_font,
            fg_color="#1e40af",
            hover_color="#1e3a8a",
            width=60,
            height=25,
            command=lambda e=email: self.handle_switch_account(e)
        )
        switch_btn.pack(side="left", padx=(0, 5))
        
        # 删除按钮
        delete_btn = ctk.CTkButton(
            action_frame,
            text="删除",
            font=self.small_font,
            fg_color="#991b1b",
            hover_color="#7f1d1d",
            width=60,
            height=25,
            command=lambda e=email: self.handle_delete_account(e)
        )
        delete_btn.pack(side="left")

    def mask_token(self, token):
        """对token进行脱敏处理，只显示前4位和后4位，中间用两个星号替代"""
        if not token or len(token) < 8:
            return token  # 如果token太短，不进行脱敏
        
        return f"{token[:4]}**{token[-4:]}"

    def get_account_token(self, email):
        """获取指定邮箱账号的token"""
        for account in self.accounts:
            if account["email"] == email:
                return account.get("token", "")
        return ""

    def handle_add_account(self):
        """处理添加新账号按钮点击事件"""
        # 创建添加账号对话框
        add_dialog = ctk.CTkToplevel(self.root)
        add_dialog.title("添加新账号")
        add_dialog.geometry("400x250")
        add_dialog.resizable(False, False)
        
        # 在对话框最前面显示
        add_dialog.transient(self.root)
        add_dialog.grab_set()
        
        # 确保对话框居中显示
        def center_dialog():
            add_dialog.update_idletasks()
            width = add_dialog.winfo_width()
            height = add_dialog.winfo_height()
            x = (add_dialog.winfo_screenwidth() // 2) - (width // 2)
            y = (add_dialog.winfo_screenheight() // 2) - (height // 2)
            add_dialog.geometry(f"{width}x{height}+{x}+{y}")
        
        add_dialog.after(10, center_dialog)
        
        # 添加标题
        title_label = ctk.CTkLabel(
            add_dialog, 
            text="添加新账号", 
            font=self.title_font
        )
        title_label.pack(pady=(20, 15))
        
        # 创建表单框架
        form_frame = ctk.CTkFrame(add_dialog, fg_color="transparent")
        form_frame.pack(fill="x", padx=20, pady=5)
        
        # 邮箱输入
        email_label = ctk.CTkLabel(
            form_frame, 
            text="邮箱:", 
            font=self.normal_font,
            width=60,
            anchor="e"
        )
        email_label.grid(row=0, column=0, padx=(0, 10), pady=10, sticky="e")
        
        email_entry = ctk.CTkEntry(
            form_frame,
            width=250,
            font=self.normal_font,
            placeholder_text="请输入账号邮箱"
        )
        email_entry.grid(row=0, column=1, pady=10, sticky="w")
        
        # Token输入
        token_label = ctk.CTkLabel(
            form_frame, 
            text="Token:", 
            font=self.normal_font,
            width=60,
            anchor="e"
        )
        token_label.grid(row=1, column=0, padx=(0, 10), pady=10, sticky="e")
        
        token_entry = ctk.CTkEntry(
            form_frame,
            width=250,
            font=self.normal_font,
            placeholder_text="请输入账号Token"
        )
        token_entry.grid(row=1, column=1, pady=10, sticky="w")
        
        # 按钮区域
        button_frame = ctk.CTkFrame(add_dialog, fg_color="transparent")
        button_frame.pack(fill="x", padx=20, pady=(15, 20))
        
        # 取消按钮
        cancel_btn = ctk.CTkButton(
            button_frame,
            text="取消",
            font=self.normal_font,
            fg_color="#4b5563",
            hover_color="#374151",
            width=100,
            command=add_dialog.destroy
        )
        cancel_btn.pack(side="left", padx=(50, 10))
        
        # 保存按钮
        def save_account():
            # 获取输入的值
            email = email_entry.get().strip()
            token = token_entry.get().strip()
            
            # 简单验证
            if not email:
                messagebox.showerror("错误", "请输入邮箱地址", parent=add_dialog)
                return
            
            if not token:
                messagebox.showerror("错误", "请输入Token", parent=add_dialog)
                return
            
            # 添加新账号
            success, message = self.add_account(email, token)
            
            if success:
                # 保存成功后刷新账号列表
                messagebox.showinfo("成功", message, parent=add_dialog)
                add_dialog.destroy()
                self.refresh_account_list()
            else:
                messagebox.showerror("错误", message, parent=add_dialog)
        
        save_btn = ctk.CTkButton(
            button_frame,
            text="保存",
            font=self.normal_font,
            fg_color="#10b981",
            hover_color="#059669",
            width=100,
            command=save_account
        )
        save_btn.pack(side="right", padx=(10, 50))

    def handle_switch_account(self, email):
        """处理切换账号按钮点击事件"""
        # 显示确认对话框
        result = messagebox.askyesno("确认切换", f"确定要切换到账号 {email} 吗？")
        if result:
            # 查找账号信息
            account_info = None
            for account in self.accounts:
                if account["email"] == email:
                    account_info = account
                    break
            
            if account_info:
                # 在这里添加切换账号的具体实现
                print(f"正在切换到账号: {email}")
                
                # 账号切换成功后的处理
                messagebox.showinfo("成功", f"已成功切换到账号: {email}")
                
                # 切换回首页标签页
                self.handle_home_click()

    def handle_delete_account(self, email):
        """处理删除账号按钮点击事件"""
        # 显示确认对话框
        result = messagebox.askyesno("确认删除", f"确定要删除账号 {email} 吗？\n此操作不可撤销。")
        if result:
            # 执行删除账号操作
            success = self.delete_account(email)
            if success:
                messagebox.showinfo("成功", f"已成功删除账号: {email}")
                # 刷新账号列表
                self.refresh_account_list()
            else:
                messagebox.showerror("错误", "删除账号失败")

    def delete_account(self, email):
        """从账号列表中删除指定邮箱的账号"""
        # 查找并删除账号
        for i, account in enumerate(self.accounts):
            if account["email"] == email:
                del self.accounts[i]
                # 保存更改到文件
                return self.save_accounts()
        return False

    def refresh_account_list(self, reset_page=True):
        """刷新账号管理页面的账号列表"""
        # 如果需要重置页码，将页码设为1
        if reset_page:
            self.account_page = 1
        
        # 如果当前在账号管理页面，刷新显示
        if hasattr(self, 'account_frame'):
            # 保存当前的tab状态，因为handle_account_click会检查状态
            original_tab = self.current_tab
            
            # 暂时设置为非account状态，以确保handle_account_click会执行更新
            self.current_tab = "temp"
            
            # 移除旧的账号框架
            self.account_frame.destroy()
            
            # 恢复正确的tab状态
            self.current_tab = original_tab
            
            # 重新创建账号管理页面
            self.show_account_content()

    def setup_encryption(self):
        """设置加密所需的密钥"""
        # 使用一个固定的 salt 和密码
        # 在实际应用中，salt 应该是随机生成并安全存储的
        self.salt = b'cursor_switcher_salt'  # 固定的 salt
        password = b'cursor_switcher_secure_password'  # 固定的密码
        
        # 使用密码和salt生成密钥
        kdf = PBKDF2HMAC(
            algorithm=hashes.SHA256(),
            length=32,
            salt=self.salt,
            iterations=100000,
        )
        key = base64.urlsafe_b64encode(kdf.derive(password))
        self.cipher = Fernet(key)
    
    def encrypt_data(self, data):
        """加密数据"""
        # 将数据转换为JSON字符串，然后加密
        json_data = json.dumps(data, ensure_ascii=False).encode('utf-8')
        encrypted_data = self.cipher.encrypt(json_data)
        return encrypted_data
    
    def decrypt_data(self, encrypted_data):
        """解密数据"""
        try:
            # 解密数据，然后解析JSON
            decrypted_data = self.cipher.decrypt(encrypted_data)
            return json.loads(decrypted_data.decode('utf-8'))
        except Exception as e:
            print(f"解密数据时出错: {e}")
            return []

    def load_accounts(self):
        """加载保存的账号数据（解密）"""
        try:
            if os.path.exists(self.accounts_file_path):
                with open(self.accounts_file_path, 'rb') as f:  # 使用二进制模式读取
                    encrypted_data = f.read()
                    if encrypted_data:  # 确保文件不为空
                        return self.decrypt_data(encrypted_data)
            return []  # 如果文件不存在或为空返回空列表
        except Exception as e:
            print(f"加载账号数据时出错: {e}")
            return []

    def save_accounts(self):
        """保存账号数据到文件（加密）"""
        try:
            encrypted_data = self.encrypt_data(self.accounts)
            with open(self.accounts_file_path, 'wb') as f:  # 使用二进制模式写入
                f.write(encrypted_data)
            return True
        except Exception as e:
            print(f"保存账号数据时出错: {e}")
            return False

    def add_account(self, email, token):
        """添加新账号"""
        # 检查是否已存在相同邮箱的账号
        for account in self.accounts:
            if account["email"] == email:
                return False, "该邮箱已存在"
        
        # 添加新账号
        self.accounts.append({
            "email": email,
            "token": token,
            "status": "已激活",  # 默认状态
            "added_date": self.get_current_date()
        })
        
        # 保存到文件
        if self.save_accounts():
            return True, "账号添加成功"
        else:
            return False, "保存账号失败"

    def get_current_date(self):
        """获取当前日期字符串"""
        from datetime import datetime
        return datetime.now().strftime("%Y-%m-%d")

    def fetch_notifications(self):
        """从API获取通知列表"""
        try:
            response = requests.get(f"{self.api_base_url}/notifications", timeout=5)
            if response.status_code == 200:
                notifications_data = response.json()
                # 转换为应用需要的格式: [(message, linkUrl), ...]
                notifications = [(item.get('message', ''), item.get('linkUrl', '#')) for item in notifications_data]
                return notifications
            else:
                print(f"获取通知失败，状态码: {response.status_code}")
                return []
        except Exception as e:
            print(f"获取通知时出错: {e}")
            return []

    def load_license_info(self):
        """加载许可证信息"""
        key = self.key_entry.get()
        if not key:
            self.key_status_value.configure(text="未输入秘钥")
            return
        
        try:
            response = requests.get(f"{self.api_base_url}/license/{key}", timeout=5)
            if response.status_code == 200:
                license_data = response.json()
                print(f"获取的许可证数据: {license_data}")  # 调试信息
                
                # 更新UI显示
                status_text = f"{license_data.get('key_status', '未知')}  {license_data.get('account_type', '未知')}  {license_data.get('days_left', '未知')}"
                self.key_status_value.configure(text=status_text)
                
                # 更新本地mock数据，以便其他部分也可以使用这些信息
                self.mock_data['key_status'] = license_data.get('key_status', '未知')
                self.mock_data['account_type'] = license_data.get('account_type', '未知')
                self.mock_data['days_left'] = license_data.get('days_left', '未知')
                
                # 修正积分使用信息 - 使用正确的字段名称和逻辑
                total_points = int(license_data.get('cursorPoolUsageTotal', '1000'))
                used_points = int(license_data.get('cursorPoolUsageUsed', '0'))
                
                print(f"积分信息: 总积分={total_points}, 已用积分={used_points}")  # 调试信息
                
                self.mock_data['cursor_pool_usage']['total'] = total_points
                self.mock_data['cursor_pool_usage']['current'] = used_points
                
                # 手动更新进度条
                self.update_cursor_pool_display(used_points, total_points)
                
            else:
                self.key_status_value.configure(text="获取秘钥信息失败")
                print(f"获取许可证信息失败，状态码: {response.status_code}")
        except Exception as e:
            self.key_status_value.configure(text="服务暂时无法访问")
            print(f"获取许可证信息时出错: {e}")

    def update_cursor_pool_display(self, used, total):
        """直接更新Cursor Pool额度使用量显示"""
        # 遍历所有子控件查找Cursor Pool使用量的进度条和标签
        for widget in self.root.winfo_children():
            if isinstance(widget, ctk.CTkFrame):
                self._find_and_update_pool_widgets(widget, used, total)
        
        # 刷新界面
        self.root.update()

    def _find_and_update_pool_widgets(self, widget, used, total):
        """递归查找并更新Pool使用量显示组件"""
        if hasattr(widget, 'winfo_children'):
            for child in widget.winfo_children():
                if isinstance(child, ctk.CTkFrame):
                    # 检查标签是否含有"Cursor Pool额度使用量"
                    has_pool_label = False
                    for inner_child in child.winfo_children():
                        if isinstance(inner_child, ctk.CTkLabel) and hasattr(inner_child, 'cget'):
                            text = inner_child.cget('text')
                            if text == "Cursor Pool额度使用量":
                                has_pool_label = True
                                break
                    
                    # 如果找到了Cursor Pool标签，更新它的子组件
                    if has_pool_label:
                        print("找到了Cursor Pool额度使用量标签")
                        for frame in child.winfo_children():
                            if isinstance(frame, ctk.CTkFrame) and frame.winfo_children():
                                for item in frame.winfo_children():
                                    # 更新进度条
                                    if isinstance(item, ctk.CTkProgressBar):
                                        print(f"更新进度条: {used}/{total}")
                                        if total > 0:
                                            item.set(used / total)
                                    # 更新文本标签
                                    elif isinstance(item, ctk.CTkLabel) and hasattr(item, 'cget'):
                                        if '/' in item.cget('text'):
                                            print(f"更新标签文本: {used}/{total}")
                                            item.configure(text=f"{used}/{total}")
                    else:
                        # 递归查找子框架
                        self._find_and_update_pool_widgets(child, used, total)

    def check_api_availability(self):
        """检查API是否可用"""
        try:
            response = requests.get(f"{self.api_base_url}/notifications", timeout=2)
            if response.status_code == 200:
                return True
            else:
                messagebox.showinfo("服务提示", "服务器响应异常，部分功能可能无法正常使用。")
                return False
        except:
            messagebox.showinfo("服务提示", "服务暂时无法访问，将使用本地功能继续运行。")
            return False

    def handle_prev_page(self):
        """处理上一页按钮点击事件"""
        if self.account_page > 1:
            self.account_page -= 1
            self.refresh_account_list(False)  # 不重置页码

    def handle_next_page(self):
        """处理下一页按钮点击事件"""
        total_pages = (len(self.accounts) + self.accounts_per_page - 1) // self.accounts_per_page
        if self.account_page < total_pages:
            self.account_page += 1
            self.refresh_account_list(False)  # 不重置页码

    def get_current_cursor_email(self):
        """获取当前Cursor客户端登录的邮箱"""
        try:
            # 创建CursorAccountSwitcher实例
            switcher = cursor_switcher.CursorAccountSwitcher()
            
            # 获取当前账号信息
            email, token = switcher.get_current_account()
            
            # 更新UI显示
            if email:
                # 更新数据
                self.mock_data['local_cursor_email'] = email
                self.mock_data['token'] = token  # 保存完整token供后续使用
                
                # 更新界面上的邮箱标签
                for widget in self.root.winfo_children():
                    if isinstance(widget, ctk.CTkFrame):
                        self._update_email_ui(widget, email)
                        self._update_token_ui(widget, token)
                
                # 直接更新token标签，显示前32位
                if hasattr(self, 'token_value_label'):
                    self.token_value_label.configure(text=self.get_token_prefix(token, 32))
                    print(f"更新了token显示: {self.get_token_prefix(token, 32)}")
                
                # 更新状态
                self._update_cursor_status("已连接客户端", "#065f46")
                
                # 保存或更新账号信息到cursor_accounts.json
                self.save_current_cursor_account(email, token)
                
                print(f"成功获取并更新Cursor账号: {email}")
                return email
        except Exception as e:
            # 移除错误弹窗，只在控制台打印错误
            print(f"获取Cursor账号信息出错: {e}")
            
            # 更新状态为错误
            self._update_cursor_status("连接错误", "#991b1b")
            return None

    def _update_email_ui(self, parent, email):
        """递归查找并更新所有显示邮箱的UI组件"""
        if hasattr(parent, 'winfo_children'):
            for child in parent.winfo_children():
                # 检查是否是显示邮箱的标签
                if isinstance(child, ctk.CTkLabel) and hasattr(child, 'cget'):
                    label_text = child.cget('text')
                    # 判断是否是邮箱标签 - 比较精确地匹配旧邮箱或包含@的文本
                    old_email = self.mock_data.get('local_cursor_email', '')
                    if label_text == old_email or ('@' in label_text and '.' in label_text):
                        child.configure(text=email)
                        print(f"更新了邮箱标签: {email}")
                
                # 递归处理子控件
                if hasattr(child, 'winfo_children'):
                    self._update_email_ui(child, email)

    def _update_token_ui(self, parent, token):
        """递归查找并更新所有显示token的UI组件"""
        if hasattr(parent, 'winfo_children'):
            for child in parent.winfo_children():
                # 检查是否是显示token的标签
                if isinstance(child, ctk.CTkLabel) and hasattr(child, 'cget'):
                    label_text = child.cget('text')
                    
                    # 查找左侧含有"Token:"的标签，或者当前标签文本包含xx**xx这样的格式(掩码token)
                    if "Token:" in label_text or (len(label_text) >= 8 and "**" in label_text):
                        # 如果是包含"Token:"的标签，不做修改
                        if label_text.strip() == "Token:":
                            pass 
                        # 否则更新为掩码token
                        else:
                            masked_token = self.mask_token(token)
                            child.configure(text=masked_token)
                            print(f"更新了token标签: {masked_token}")
                
                # 递归处理子控件
                if hasattr(child, 'winfo_children'):
                    self._update_token_ui(child, token)

    def _update_cursor_status(self, status_text, color="#1e3a8a"):
        """更新Cursor状态显示"""
        # 更新数据
        self.mock_data['cursor_status'] = status_text
        
        # 查找状态按钮并更新
        for widget in self.root.winfo_children():
            if isinstance(widget, ctk.CTkFrame):
                self._find_and_update_status_button(widget, status_text, color)

    def _find_and_update_status_button(self, parent, status_text, color):
        """递归查找并更新状态按钮"""
        if hasattr(parent, 'winfo_children'):
            for child in parent.winfo_children():
                # 查找框架
                if isinstance(child, ctk.CTkFrame) and hasattr(child, 'winfo_children'):
                    # 在框架中查找标签和按钮
                    status_label = None
                    status_button = None
                    
                    for item in child.winfo_children():
                        if isinstance(item, ctk.CTkLabel) and hasattr(item, 'cget'):
                            if item.cget('text') == "本地Cursor状态":
                                status_label = item
                        elif isinstance(item, ctk.CTkButton) and hasattr(item, 'cget'):
                            # 查找显示Cursor状态的按钮
                            if "已注入" in item.cget('text') or "客户端" in item.cget('text'):
                                status_button = item
                    
                    # 如果找到了状态按钮，更新它
                    if status_button:
                        status_button.configure(text=status_text, fg_color=color)
                        return
                
                # 递归处理子控件
                if hasattr(child, 'winfo_children'):
                    self._find_and_update_status_button(child, status_text, color)

    def get_token_prefix(self, token, length=32):
        """显示token的前N位字符"""
        if not token:
            return "未获取到token"
        
        # 返回token的前N位
        return token[:length] if len(token) >= length else token

    def save_current_cursor_account(self, email, token):
        """保存或更新当前Cursor账号到accounts.json文件"""
        if not email or not token:
            print("邮箱或Token为空，跳过保存")
            return False
        
        # 检查账号是否已存在
        account_exists = False
        for i, account in enumerate(self.accounts):
            if account["email"] == email:
                # 更新现有账号的token
                self.accounts[i]["token"] = token
                self.accounts[i]["status"] = "已激活"
                self.accounts[i]["updated_date"] = self.get_current_date()
                account_exists = True
                print(f"更新已存在的账号: {email}")
                break
        
        # 如果账号不存在，添加为新账号
        if not account_exists:
            self.accounts.append({
                "email": email,
                "token": token,
                "status": "已激活",
                "added_date": self.get_current_date(),
                "updated_date": self.get_current_date()
            })
            print(f"添加新账号到列表: {email}")
        
        # 保存到文件
        if self.save_accounts():
            print(f"已成功保存账号信息到文件")
            return True
        else:
            print(f"保存账号信息到文件失败")
            return False

if __name__ == "__main__":
    # 确保高DPI显示在各平台正常工作
    if platform.system() == "Windows":
        from ctypes import windll
        windll.shcore.SetProcessDpiAwareness(1)
    
    root = ctk.CTk()
    
    # 处理macOS下的菜单栏
    if platform.system() == "Darwin":
        # 创建macOS风格的应用菜单
        menu = tk.Menu(root)
        app_menu = tk.Menu(menu, tearoff=0)
        app_menu.add_command(label="关于CP控制面板")
        app_menu.add_separator()
        app_menu.add_command(label="退出", command=root.quit)
        menu.add_cascade(label="CP控制面板", menu=app_menu)
        root.config(menu=menu)
    
    app = MainApplication(root)
    root.mainloop() 